home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 2003-07-17 | 91.1 KB | 2,829 lines
// Copyright (C) 1997-2002 Alias|Wavefront, // a division of Silicon Graphics Limited. // // The information in this file is provided for the exclusive use of the // licensees of Alias|Wavefront. Such users have the right to use, modify, // and incorporate this code into other products for purposes authorized // by the Alias|Wavefront license agreement, without fee. // // ALIAS|WAVEFRONT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, // INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO // EVENT SHALL ALIAS|WAVEFRONT BE LIABLE FOR ANY SPECIAL, INDIRECT OR // CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, // DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. // includeEffectsGlobals(); global proc includeSurfaceFlowGlobals() // // Description: // // This is the procedure that users will need to call once // to enable the surface flow scripts to be used from the // command line or from their scripts. The UI does this // automatically, so this is not needed if just using the // menus. // { } proc string surfaceFlowTag( string $object ) // // Description: // // Each surface flow object in a scene has a unique tag associated with // it. This is used when editing the particle objects' expressions. This // procedure returns the tag for the given surface flow object. // { if( isSurfaceFlow( $object ) == 0 ) { return ""; } string $tag = `getAttr ($object+".surfaceFlowTag")`; return $tag; } proc string getUniqueSurfaceFlowTag() // // Description: // // Each surface flow object in a scene has a unique tag associated with // it. This is used when editing the particle objects' expressions. When // creating a new surface flow object, this procedure will return a unique // tag for that surface flow object to use. // { string $allNodes[] = `ls`; string $surfaceFlowTags[]; clear( $surfaceFlowTags ); int $i; for( $i = 0; $i < size( $allNodes ); $i ++ ) { if( isSurfaceFlow( $allNodes[$i] ) == 1 ) { string $tag = surfaceFlowTag( $allNodes[$i] ); $surfaceFlowTags = appendSingleToStringArray( $surfaceFlowTags, surfaceFlowTag($allNodes[$i]) ); } } string $result = ""; int $currentValue = 0; int $done = 0; while( $done == 0 ) { string $testString = ("_SF_TAG_"+$currentValue); if( findInStringArray( $testString, $surfaceFlowTags ) == -1 ) { $result = $testString; $done = 1; } $currentValue ++; } return $result; } ///////////////////////////////////////////////////////////////////////////////// proc string[] surfaceFlowEffectAttrConnections( string $object, string $particle ) // // Returns string array. // // The first element is the actual attribute name on the particle object that // holds the effectStrength values for the given surface flow group. This is only // the attribute name without the particle object's name. This makes it easier to // give the deleteAtr command. // // The remaining elements are disconnectAttr pairs that should be broken (in the order // given) before the deleteAttr can be called for the attribute. // { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } string $particleShape[] = `ls -o -dag -s -type particle $particle`; if( isParticleInSurfaceFlow($object, $particleShape[0]) == 1 ) { // // First put the attribute name in the result string. // string $effectStrengthAttr[] = `listConnections -source true -destination false -shapes true -plugs 0 ($object+".effectStrengthAttribute")`; int $index = findInStringArray( $particleShape[0], $effectStrengthAttr ); if( $index == -1 ) { return $result; } $effectStrengthAttr = `listConnections -source true -destination false -shapes true -plugs 1 -connections 1 ($object+".effectStrengthAttribute")`; $actualAttr = $effectStrengthAttr[$index*2+1]; string $tokens[]; clear( $tokens ); tokenize( $actualAttr, ".", $tokens ); $result[0] = $tokens[1]; string $outputsFromActualAttr[] = `listConnections -source false -destination true -plugs 1 -shapes 1 $actualAttr`; string $inputsToActualAttr[] = `listConnections -source true -destination false -plugs 1 -shapes 1 $actualAttr`; int $j; for( $j = 0; $j < size($inputsToActualAttr); $j ++ ) { $result = appendSingleToStringArray( $result, $inputsToActualAttr[$j] ); $result = appendSingleToStringArray( $result, $actualAttr ); } for( $j = 0; $j < size($outputsFromActualAttr); $j ++ ) { $result = appendSingleToStringArray( $result, $actualAttr ); $result = appendSingleToStringArray( $result, $outputsFromActualAttr[$j] ); } } return $result; } proc string[] surfaceFlowEffectStrengthObjects( string $object, string $particle ) // // Returns an array off all of the manipPosition attributes on $particle, that represent $object. // These connections can { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } string $particleShape[] = `ls -o -dag -s -type particle $particle`; if( isParticleInSurfaceFlow($object, $particleShape[0]) == 1 ) { string $flowingParticles[] = surfaceFlowParticles( $object ); int $index = findInStringArray( $particleShape[0], $flowingParticles ); if( $index == -1 ) { return $result; } // // Now put the ramp name in the result string. // string $effectStrengthRamp[] = `listConnections -source true -destination false -shapes true -plugs 0 ($object+".effectStrengthRamp")`; $result[0] = $effectStrengthRamp[$index]; // // Now put the array mapper name in the result string. // string $effectStrengthMapper[] = `listConnections -source true -destination false -shapes true -plugs 0 ($object+".effectStrengthArrayMapper")`; $result[1] = $effectStrengthMapper[$index]; } return $result; } proc string[] surfaceFlowManipArrayMappers( string $object, string $particle ) // // Returns an array off all of the manipPosition attributes on $particle, that represent $object. // These connections can { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } string $particleShape[] = `ls -o -dag -s -type particle $particle`; if( isParticleInSurfaceFlow($object, $particleShape[0]) == 1 ) { string $arrayMappers[] = `listConnections -source true -destination false -shapes true -plugs 0 ($object+".manipPositionArrayMapper")`; int $i; for( $i = 0; $i < size($arrayMappers); $i ++ ) { string $inputs[] = `listConnections -source true -destination false -shapes true -plugs false ($arrayMappers[$i]+".vCoordPP")`; if( $inputs[0] == $particleShape[0] ) { $result = appendSingleToStringArray( $result, $arrayMappers[$i] ); } } } return $result; } proc string[] surfaceFlowManipPositionAttributes( string $object, string $particle ) // // Returns an array off all of the manipPosition attributes on $particle, that represent $object. // These connections can { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } string $particleShape[] = `ls -o -dag -s -type particle $particle`; if( isParticleInSurfaceFlow($object, $particleShape[0]) == 1 ) { string $manipPositionAttrNodes[] = `listConnections -source true -destination false -shapes true -plugs 0 ($object+".manipPositionAttribute")`; int $index = findInStringArray( $particleShape[0], $manipPositionAttrNodes ); if( $index == -1 ) { $result[0] = "0"; return $result; } string $manipPositionAttrPlugs[] = `listConnections -source true -destination false -shapes true -plugs 1 -connections 1 ($object+".manipPositionAttribute")`; int $manipAttrCount = 0; int $i; for( $i = 0; $i < size( $manipPositionAttrNodes ); $i ++ ) { if( $manipPositionAttrNodes[$i] == $particleShape[0] ) { $manipAttrCount ++; } } $result[0] = $manipAttrCount; for( $i = 0; $i < size( $manipPositionAttrNodes ); $i ++ ) { if( $manipPositionAttrNodes[$i] == $particleShape[0] ) { string $actualAttr = $manipPositionAttrPlugs[$i*2+1]; string $tokens[]; clear( $tokens ); tokenize( $actualAttr, ".", $tokens ); $result = appendSingleToStringArray( $result, $tokens[1] ); } } for( $i = 0; $i < size( $manipPositionAttrNodes ); $i ++ ) { if( $manipPositionAttrNodes[$i] == $particleShape[0] ) { string $actualAttr = $manipPositionAttrPlugs[$i*2+1]; string $outputsFromActualAttr[] = `listConnections -source false -destination true -plugs 1 -shapes 1 $actualAttr`; string $inputsToActualAttr[] = `listConnections -source true -destination false -plugs 1 -shapes 1 $actualAttr`; int $j; for( $j = 0; $j < size($inputsToActualAttr); $j ++ ) { $result = appendSingleToStringArray( $result, $inputsToActualAttr[$j] ); $result = appendSingleToStringArray( $result, $actualAttr ); } for( $j = 0; $j < size($outputsFromActualAttr); $j ++ ) { $result = appendSingleToStringArray( $result, $actualAttr ); $result = appendSingleToStringArray( $result, $outputsFromActualAttr[$j] ); } } } } return $result; } proc string[] surfaceFlowGoalWeightAttribute( string $object, string $particle ) // // Returns string array. // // The first element is the actual attribute name on the particle object that // holds the effectStrength values for the given surface flow group. This is only // the attribute name without the particle object's name. This makes it easier to // give the deleteAtr command. // // The remaining elements are disconnectAttr pairs that should be broken (in the order // given) before the deleteAttr can be called for the attribute. // { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } string $particleShape[] = `ls -o -dag -s -type particle $particle`; if( isParticleInSurfaceFlow($object, $particleShape[0]) == 1 ) { // // First put the attribute name in the result string. // string $goalWeightAttr[] = `listConnections -source true -destination false -shapes true -plugs 0 ($object+".goalWeightAttribute")`; int $index = findInStringArray( $particleShape[0], $goalWeightAttr ); if( $index == -1 ) { return $result; } $goalWeightAttr = `listConnections -source true -destination false -shapes true -plugs 1 -connections 1 ($object+".goalWeightAttribute")`; $actualAttr = $goalWeightAttr[$index*2+1]; string $tokens[]; clear( $tokens ); tokenize( $actualAttr, ".", $tokens ); tokenize( $tokens[1], "[", $tokens ); tokenize( $tokens[1], "]", $tokens ); $result[0] = $tokens[0]; string $outputsFromActualAttr[] = `listConnections -source false -destination true -plugs 1 -shapes 1 $actualAttr`; string $inputsToActualAttr[] = `listConnections -source true -destination false -plugs 1 -shapes 1 $actualAttr`; int $j; for( $j = 0; $j < size($inputsToActualAttr); $j ++ ) { $result = appendSingleToStringArray( $result, $inputsToActualAttr[$j] ); $result = appendSingleToStringArray( $result, $actualAttr ); } for( $j = 0; $j < size($outputsFromActualAttr); $j ++ ) { $result = appendSingleToStringArray( $result, $actualAttr ); $result = appendSingleToStringArray( $result, $outputsFromActualAttr[$j] ); } } return $result; } proc string[] surfaceFlowAdjustedAgeNormalizedAttribute( string $object, string $particle ) // // Returns string array. // // The first element is the actual attribute name on the particle object that // holds the effectStrength values for the given surface flow group. This is only // the attribute name without the particle object's name. This makes it easier to // give the deleteAtr command. // // The remaining elements are disconnectAttr pairs that should be broken (in the order // given) before the deleteAttr can be called for the attribute. // { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } string $particleShape[] = `ls -o -dag -s -type particle $particle`; if( isParticleInSurfaceFlow($object, $particleShape[0]) == 1 ) { // // First put the attribute name in the result string. // string $adjustedAgeNormalizedAttr[] = `listConnections -source true -destination false -shapes true -plugs 0 ($object+".adjustedAgeNormalizedAttribute")`; int $index = findInStringArray( $particleShape[0], $adjustedAgeNormalizedAttr ); if( $index == -1 ) { return $result; } $adjustedAgeNormalizedAttr = `listConnections -source true -destination false -shapes true -plugs 1 -connections 1 ($object+".adjustedAgeNormalizedAttribute")`; $actualAttr = $adjustedAgeNormalizedAttr[$index*2+1]; string $tokens[]; clear( $tokens ); tokenize( $actualAttr, ".", $tokens ); $result[0] = $tokens[1]; string $outputsFromActualAttr[] = `listConnections -source false -destination true -plugs 1 -shapes 1 $actualAttr`; string $inputsToActualAttr[] = `listConnections -source true -destination false -plugs 1 -shapes 1 $actualAttr`; int $j; for( $j = 0; $j < size($inputsToActualAttr); $j ++ ) { $result = appendSingleToStringArray( $result, $inputsToActualAttr[$j] ); $result = appendSingleToStringArray( $result, $actualAttr ); } for( $j = 0; $j < size($outputsFromActualAttr); $j ++ ) { $result = appendSingleToStringArray( $result, $actualAttr ); $result = appendSingleToStringArray( $result, $outputsFromActualAttr[$j] ); } } return $result; } //////////////////////////////////////////////////////////////////////////// proc string[] surfaceFlowMainManips( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } $result = getMarkedObjects( $object, "surfaceFlowMainManips" ); return $result; } proc string[] surfaceFlowSubManips( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } $result = getMarkedObjects( $object, "surfaceFlowSubManips" ); return $result; } proc string[] surfaceFlowMainRamps( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } $result = getMarkedObjects( $object, "surfaceFlowMainRamps" ); return $result; } proc string[] surfaceFlowSubRamps( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } $result = getMarkedObjects( $object, "surfaceFlowSubRamps" ); return $result; } proc string[] surfaceFlowMainLofts( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } $result = getMarkedObjects( $object, "surfaceFlowMainLofts" ); return $result; } proc string[] surfaceFlowSubLofts( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } $result = getMarkedObjects( $object, "surfaceFlowSubLofts" ); return $result; } proc string[] surfaceFlowMainResolutionPlanes( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } $result = getMarkedObjects( $object, "surfaceFlowMainResolutionPlanes" ); return $result; } proc string[] surfaceFlowSubResolutionPlanes( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } $result = getMarkedObjects( $object, "surfaceFlowSubResolutionPlanes" ); return $result; } proc string[] surfaceFlowMainEdgeCurves( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } $result = getMarkedObjects( $object, "surfaceFlowMainEdgeCurves" ); return $result; } proc string[] surfaceFlowSubEdgeCurves( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } $result = getMarkedObjects( $object, "surfaceFlowSubEdgeCurves" ); return $result; } proc string[] surfaceFlowMainMinCurves( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } $result = getMarkedObjects( $object, "surfaceFlowMainMinCurves" ); return $result; } proc string[] surfaceFlowSubMinCurves( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } $result = getMarkedObjects( $object, "surfaceFlowSubMinCurves" ); return $result; } proc string[] surfaceFlowMainMaxCurves( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } $result = getMarkedObjects( $object, "surfaceFlowMainMaxCurves" ); return $result; } proc string[] surfaceFlowSubMaxCurves( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } $result = getMarkedObjects( $object, "surfaceFlowSubMaxCurves" ); return $result; } ///////////////////////////////////////////////////////////////////////////////////// proc string[] surfaceFlowNodesToDelete( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { return $result; } $result = getMarkedObjects( $object, "nodesToDelete" ); return $result; } proc markNodesNonHistoricallyInteresting( string $object ) { if( isSurfaceFlow( $object ) == 0 ) { return; } string $allNodes[] = surfaceFlowNodesToDelete( $object ); int $i; for( $i = 0; $i < size($allNodes); $i ++ ) { string $thisObject = $allNodes[$i]; if( ( findInStringArray( $thisObject, surfaceFlowParticles( $object ) ) == -1 ) && ( $thisObject != surfaceFlowEmitter( $object ) ) ) { setAttr ($thisObject+".isHistoricallyInteresting") 0; } } } proc int cleanupSurfaceFlowAttributes( string $flow ) { if( isSurfaceFlow( $flow ) == 0 ) { return 0; } string $scalarAttrs[] = `listAttr -scalar -keyable $flow`; int $i; for( $i = 0; $i < size( $scalarAttrs ); $i ++ ) { if( ( gmatch( $scalarAttrs[$i], "minAgeRatio_*" ) == 1 ) || ( gmatch( $scalarAttrs[$i], "maxAgeRatio_*" ) == 1 ) || ( gmatch( $scalarAttrs[$i], "goalWeight_*" ) == 1 ) ) { string $outputs[] = `listConnections -source false -destination true ($flow+"."+$scalarAttrs[$i])`; if( size( $outputs ) == 0 ) { deleteAttr -at $scalarAttrs[$i] $flow; } } } return 1; } ////////////////////////////////////////////////////////////////////////// proc markNewNonDagNodes( string $flowGroup, string $oldNodes[], string $newNodes[] ) { string $nodesToMark[]; clear( $nodesToMark ); if( isSurfaceFlow( $flowGroup ) == 0 ) { return; } string $oldNodesToDelete[] = surfaceFlowNodesToDelete( $flowGroup ); int $i; for( $i = 0; $i < size( $newNodes ); $i ++ ) { // // If this object is not in the $oldNodes array, then it was // created during the execution of this script. // if( findInStringArray( $newNodes[$i], $oldNodes ) == -1 ) { // // We only want to mark non-DAG nodes for deletion in this way, // since all of the DAG objects created (except for the particles) // are under the main group node in the DAG and can be deleted // by deleting the main group. // string $dagNodes[] = `ls -type transform -type shape $newNodes[$i]`; if( size( $dagNodes ) == 0 ) { // // Only mark it if it is not already in the list of nodes to // delete for this surface flow group. This should never // happen, but just in case... // if( findInStringArray( $newNodes[$i], $oldNodesToDelete ) == -1 ) { markObjectWithAttribute( $newNodes[$i], $flowGroup, "nodesToDelete" ); } } } } } proc string makeSurfaceFlowGroup( string $surface, string $name, string $type, int $controlResolution, int $subControlResolution, int $manipResolution, float $goalWeight, float $emitterRate, float $minAgeRatio, float $maxAgeRatio ) { $controlResolution = max(2,$controlResolution); $subControlResolution = max(0,$subControlResolution); $manipResolution = max( 3, $manipResolution ); $goalWeight = max( 0, min( 1, $goalWeight ) ); $emitterRate = max( 0, $emitterRate ); $minAgeRatio = max( 0, min( 1, $minAgeRatio ) ); $maxAgeRatio = max( 0, min( 1, $maxAgeRatio ) ); // // Check to see if the given surface is really a surface, // and get the shape from it. // string $surfaceShape = ""; if( `objExists $surface` == 0 ) { error("Object, \""+$surface+"\", does not exists. Can not create a surface flow group."); } string $surfaceShapes[] = `ls -dag -type nurbsSurface $surface`; if( size( $surfaceShapes ) == 0 ) { // // No nurbsSurface shapes that can be found from the given name. // error("No nurbsSurface shape or transform matches the name, \""+$surface+"\". Can not create a surface flow group."); } else if( size( $surfaceShapes ) > 1 ) { // // Too many nurbsSurface shapes match the given name. Tell the // user to be more specific. // error("More than one nurbsSurface shape found using the name, \""+$surface+"\". Can not create a surface flow group."); } else { $surfaceShape = $surfaceShapes[0]; } // // These were changd to always use [0-1] because now the // "superDuplicated" surface is rebuilt to always be between // [0-1]. That allows the effect to respond to any changes made // to the original surface that might alter the way that it is // parameterized. // float $surfaceMinU = 0; // `getAttr ($surfaceShape+".minValueU")`; float $surfaceMaxU = 1; // `getAttr ($surfaceShape+".maxValueU")`; float $surfaceMinV = 0; // `getAttr ($surfaceShape+".minValueV")`; float $surfaceMaxV = 1; // `getAttr ($surfaceShape+".maxValueV")`; group -empty; if( $name == "" ) { rename "SurfaceFlow#"; } else { rename $name; } string $flowGroup = getSelectedObject( 0 ); // // First, lock and hide all of the transformation attributes // for the surface flow group. This object is not intended // to be transformed. // lockTransformations( $flowGroup ); superDuplicateSurface( $surfaceShape ); string $newSurface = getSelectedObject( 0 ); // // We rebuild our copy of the surface to guarantee the parameterization // of the surface that we use. This allows the user to do literally anything // to the original surface, while the surface flow maintains a consistent // parameterization to work with. // rebuildSurface -ch 1 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 1 -kc 0 -su 4 -du 3 -sv 4 -dv 3 -tol 0.01 -dir 2 $newSurface; setAttr ($newSurface+".template") 1; hide $newSurface; markObjectWithAttribute($surfaceShape,$flowGroup,"referenceFlowSurface"); markObjectWithAttribute($newSurface,$flowGroup,"actualFlowSurface"); float $minValue, $maxValue, $range; if( $type == "u" ) { $minValue = $surfaceMinU; $maxValue = $surfaceMaxU; $range = $surfaceMaxU - $surfaceMinU; } else if( ($type == "-u") || ( `about -mac` && ($type == "minusU") ) ) // Fix for 156627 { $minValue = $surfaceMaxU; $maxValue = $surfaceMinU; $range = $surfaceMinU - $surfaceMaxU; $type = "u"; } else if( $type == "v" ) { $minValue = $surfaceMinV; $maxValue = $surfaceMaxV; $range = $surfaceMaxV - $surfaceMinV; } else if( ($type == "-v") || ( `about -mac` && ($type == "minusV") ) ) { $minValue = $surfaceMaxV; $maxValue = $surfaceMinV; $range = $surfaceMinV - $surfaceMaxV; $type = "v"; } else { error("Unknown surface flow type, \""+$type+"\". Can not create surfaceFlow Group."); } string $mainManips[]; clear( $mainManips ); string $subManips[]; clear( $subManips ); string $ramps[]; clear( $ramps ); string $lofts[]; clear( $lofts ); string $edgeCurves[]; clear( $edgeCurves ); string $minCurves[]; clear( $minCurves ); string $maxCurves[]; clear( $maxCurves ); string $newAttrs[]; clear( $newAttrs ); string $destAttrs[]; clear( $destAttrs ); string $destManips[]; clear( $destManips ); float $minValues[]; clear( $minValues ); float $maxValues[]; clear( $maxValues ); float $defaultValues[]; clear( $defaultValues ); addMarkingAttribute($flowGroup,"surfaceFlowMainManips",1); addMarkingAttribute($flowGroup,"surfaceFlowSubManips",1); addMarkingAttribute($flowGroup,"surfaceFlowMainRamps",1); addMarkingAttribute($flowGroup,"surfaceFlowSubRamps",1); addMarkingAttribute($flowGroup,"surfaceFlowMainLofts",1); addMarkingAttribute($flowGroup,"surfaceFlowSubLofts",1); addMarkingAttribute($flowGroup,"surfaceFlowMainResolutionPlanes",1); addMarkingAttribute($flowGroup,"surfaceFlowSubResolutionPlanes",1); addMarkingAttribute($flowGroup,"surfaceFlowMainMinCurves",1); addMarkingAttribute($flowGroup,"surfaceFlowSubMinCurves",1); addMarkingAttribute($flowGroup,"surfaceFlowMainMaxCurves",1); addMarkingAttribute($flowGroup,"surfaceFlowSubMaxCurves",1); addMarkingAttribute($flowGroup,"surfaceFlowMainEdgeCurves",1); addMarkingAttribute($flowGroup,"surfaceFlowSubEdgeCurves",1); string $locationString = ".uLocation"; string $minDistString = ".minDistance"; string $maxDistString = ".maxDistance"; string $minLocationString = ".minV"; string $maxLocationString = ".maxV"; string $subExpr = ""; string $subExprHermite = ""; string $subExprLinstep = ""; int $i; for( $i = 0; $i < $controlResolution; $i ++ ) { float $location = $minValue + $range * ($i / ($controlResolution - 1.0)); string $manip = createNormalSurfaceManip( $newSurface, $type, $location, 2, $manipResolution ); setAttr ($manip+".template") 1; markObjectWithAttribute($manip,$flowGroup,"surfaceFlowMainManips"); string $ramp = getRampFromNormalSurfaceManip( $manip ); markObjectWithAttribute($ramp,$flowGroup,"surfaceFlowMainRamps"); string $loft = getLoftFromNormalSurfaceManip( $manip ); markObjectWithAttribute($loft,$flowGroup,"surfaceFlowMainLofts"); string $resPlane = getResolutionPlaneFromNormalSurfaceManip( $manip ); markObjectWithAttribute($resPlane,$flowGroup,"surfaceFlowMainResolutionPlanes"); string $edgeCurve = getEdgeCurveFromNormalSurfaceManip( $manip ); markObjectWithAttribute($edgeCurve,$flowGroup,"surfaceFlowMainEdgeCurves"); string $minCurve = getMinCurveFromNormalSurfaceManip( $manip ); markObjectWithAttribute($minCurve,$flowGroup,"surfaceFlowMainMinCurves"); string $maxCurve = getMaxCurveFromNormalSurfaceManip( $manip ); markObjectWithAttribute($maxCurve,$flowGroup,"surfaceFlowMainMaxCurves"); // // Add the attributes to the main group to control this manipulator. // $locationString = "uLocation"; $minString = "minV"; $maxString = "maxV"; float $minSubValue = $surfaceMinV; float $maxSubValue = $surfaceMaxV; string $minLocValue = min($minSubValue,$maxSubValue); // $surfaceMinU; string $maxLocValue = max($minSubValue,$maxSubValue); // $surfaceMaxU; if( ( $type == "v" ) || ( $type == "-v" ) ) { $locationString = "vLocation"; $minString = "minU"; $maxString = "maxU"; // $minSubValue = $surfaceMinU; // $maxSubValue = $surfaceMaxU; // $minLocValue = $surfaceMinV; // $maxLocValue = $surfaceMaxV; // // Since the surface that the effect is actually working // with the now guaranteed to be parameterized between 0 // and 1, we do not need to monitor the original surface's // parametric range. // $minSubValue = 0; $maxSubValue = 1; $minLocValue = 0; $maxLocValue = 1; } string $attrName = ($locationString+$i); string $destName = $locationString; $newAttrs = appendSingleToStringArray( $newAttrs, $attrName ); $destAttrs = appendSingleToStringArray( $destAttrs, $destName ); $minValues = appendSingleToFloatArray( $minValues, $minLocValue ); $maxValues = appendSingleToFloatArray( $maxValues, $maxLocValue ); $defaultValues = appendSingleToFloatArray( $defaultValues, $location ); $destManips = appendSingleToStringArray( $destManips, $manip ); $attrName = ($minString+$i); $destName = $minString; $newAttrs = appendSingleToStringArray( $newAttrs, $attrName ); $destAttrs = appendSingleToStringArray( $destAttrs, $destName ); $minValues = appendSingleToFloatArray( $minValues, $minSubValue ); $maxValues = appendSingleToFloatArray( $maxValues, $maxSubValue ); $defaultValues = appendSingleToFloatArray( $defaultValues, $minSubValue ); $destManips = appendSingleToStringArray( $destManips, $manip ); $attrName = ($maxString+$i); $destName = $maxString; $newAttrs = appendSingleToStringArray( $newAttrs, $attrName ); $destAttrs = appendSingleToStringArray( $destAttrs, $destName ); $minValues = appendSingleToFloatArray( $minValues, $minSubValue ); $maxValues = appendSingleToFloatArray( $maxValues, $maxSubValue ); $defaultValues = appendSingleToFloatArray( $defaultValues, $maxSubValue ); $destManips = appendSingleToStringArray( $destManips, $manip ); $attrName = ("minDistance"+$i); $destName = "minDistance"; $newAttrs = appendSingleToStringArray( $newAttrs, $attrName ); $destAttrs = appendSingleToStringArray( $destAttrs, $destName ); $minValues = appendSingleToFloatArray( $minValues, 0 ); $maxValues = appendSingleToFloatArray( $maxValues, 0 ); $defaultValues = appendSingleToFloatArray( $defaultValues, 1 ); $destManips = appendSingleToStringArray( $destManips, $manip ); $attrName = ("maxDistance"+$i); $destName = "maxDistance"; $newAttrs = appendSingleToStringArray( $newAttrs, $attrName ); $destAttrs = appendSingleToStringArray( $destAttrs, $destName ); $minValues = appendSingleToFloatArray( $minValues, 0 ); $maxValues = appendSingleToFloatArray( $maxValues, 0 ); $defaultValues = appendSingleToFloatArray( $defaultValues, 2 ); $destManips = appendSingleToStringArray( $destManips, $manip ); // // Add subControl Manips // $locationString = ".uLocation"; $minDistString = ".minDistance"; $maxDistString = ".maxDistance"; $minLocationString = ".minV"; $maxLocationString = ".maxV"; if( ( $type == "v" ) || ( $type == "-v" ) ) { $locationString = ".vLocation"; $minLocationString = ".minU"; $maxLocationString = ".maxU"; } if( $i > 0 ) { int $j; for( $j = 0; $j < $subControlResolution; $j ++ ) { float $startLoc = $minSubValue + $range * ( ( $i - 1 ) / ( $controlResolution - 1.0 ) ); float $endLoc = $minSubValue + $range * ( $i / ( $controlResolution - 1.0 ) ); float $subRange = $endLoc - $startLoc; float $ratioRange = $subRange / ( $subControlResolution + 1.0 ); float $subLocation = $startLoc + ( $j + 1 ) * $ratioRange; string $subManip = createNormalSurfaceManip( $newSurface, $type, $subLocation, 2, $manipResolution ); setAttr ($subManip+".template") 1; markObjectWithAttribute($subManip,$flowGroup,"surfaceFlowSubManips"); string $subRamp = getRampFromNormalSurfaceManip( $subManip ); markObjectWithAttribute($subRamp,$flowGroup,"surfaceFlowSubRamps"); string $subLoft = getLoftFromNormalSurfaceManip( $subManip ); markObjectWithAttribute($subLoft,$flowGroup,"surfaceFlowSubLofts"); string $subResPlane = getResolutionPlaneFromNormalSurfaceManip( $subManip ); markObjectWithAttribute($subResPlane,$flowGroup,"surfaceFlowSubResolutionPlanes"); string $subEdgeCurve = getEdgeCurveFromNormalSurfaceManip( $subManip ); markObjectWithAttribute($subEdgeCurve,$flowGroup,"surfaceFlowSubEdgeCurves"); string $subMinCurve = getMinCurveFromNormalSurfaceManip( $subManip ); markObjectWithAttribute($subMinCurve,$flowGroup,"surfaceFlowSubMinCurves"); string $subMaxCurve = getMaxCurveFromNormalSurfaceManip( $subManip ); markObjectWithAttribute($subMaxCurve,$flowGroup,"surfaceFlowSubMaxCurves"); float $ratio = ($j + 1.0)/($subControlResolution + 1.0); $subExprHermite += ("\t"+$subManip+$locationString+" = hermite( $L["+($i-1)+"], $L["+$i+"], $dL["+($i-1)+"], $dL["+$i+"], "+$ratio+" );\n"); $subExprHermite += ("\t"+$subManip+$minDistString+" = hermite( $MND["+($i-1)+"], $MND["+$i+"], $dMND["+($i-1)+"], $dMND["+$i+"], "+$ratio+" );\n"); $subExprHermite += ("\t"+$subManip+$maxDistString+" = hermite( $MXD["+($i-1)+"], $MXD["+$i+"], $dMXD["+($i-1)+"], $dMXD["+$i+"], "+$ratio+" );\n"); $subExprHermite += ("\t"+$subManip+$minLocationString+" = hermite( $MNL["+($i-1)+"], $MNL["+$i+"], $dMNL["+($i-1)+"], $dMNL["+$i+"], "+$ratio+" );\n"); $subExprHermite += ("\t"+$subManip+$maxLocationString+" = hermite( $MXL["+($i-1)+"], $MXL["+$i+"], $dMXL["+($i-1)+"], $dMXL["+$i+"], "+$ratio+" );\n"); $subExprLinstep += ("\t"+$subManip+$locationString+" = $L["+($i-1)+"] + linstep( 0, 1, "+$ratio+" ) * ($L["+$i+"] - $L["+($i-1)+"] );\n"); $subExprLinstep += ("\t"+$subManip+$minDistString+" = $MND["+($i-1)+"] + linstep( 0, 1, "+$ratio+" ) * ($MND["+$i+"] - $MND["+($i-1)+"] );\n"); $subExprLinstep += ("\t"+$subManip+$maxDistString+" = $MXD["+($i-1)+"] + linstep( 0, 1, "+$ratio+" ) * ($MXD["+$i+"] - $MXD["+($i-1)+"] );\n"); $subExprLinstep += ("\t"+$subManip+$minLocationString+" = $MNL["+($i-1)+"] + linstep( 0, 1, "+$ratio+" ) * ($MNL["+$i+"] - $MNL["+($i-1)+"] );\n"); $subExprLinstep += ("\t"+$subManip+$maxLocationString+" = $MXL["+($i-1)+"] + linstep( 0, 1, "+$ratio+" ) * ($MXL["+$i+"] - $MXL["+($i-1)+"] );\n"); } } } addAttr -at message -ln "_surfaceFlowObject" $flowGroup; $mainManips = surfaceFlowMainManips( $flowGroup ); $subManips = surfaceFlowSubManips( $flowGroup ); $mainResPlanes = surfaceFlowMainResolutionPlanes( $flowGroup ); $subResPlanes = surfaceFlowSubResolutionPlanes( $flowGroup ); $ramps = surfaceFlowRamps( $flowGroup ); $lofts = surfaceFlowLofts( $flowGroup ); $minCurves = surfaceFlowMinCurves( $flowGroup ); $maxCurves = surfaceFlowMaxCurves( $flowGroup ); $edgeCurves = surfaceFlowEdgeCurves( $flowGroup ); if( $subControlResolution > 0 ) { $locationString = ".uLocation"; $minDistString = ".minDistance"; $maxDistString = ".maxDistance"; $minLocationString = ".minV"; $maxLocationString = ".maxV"; if( ( $type == "v" ) || ( $type == "-v" ) ) { $locationString = ".vLocation"; $minLocationString = ".minU"; $maxLocationString = ".maxU"; } $subExpr = "float $L[];\n"; $subExpr += "clear( $L );\n"; $subExpr += "float $MND[];\n"; $subExpr += "clear( $MND );\n"; $subExpr += "float $MXD[];\n"; $subExpr += "clear( $MXD );\n"; $subExpr += "float $MNL[];\n"; $subExpr += "clear( $MNL );\n"; $subExpr += "float $MXL[];\n"; $subExpr += "clear( $MXL );\n"; $subExpr += "\n"; $subExpr += "float $dL[];\n"; $subExpr += "clear( $dL );\n"; $subExpr += "float $dMND[];\n"; $subExpr += "clear( $dMND );\n"; $subExpr += "float $dMXD[];\n"; $subExpr += "clear( $dMXD );\n"; $subExpr += "float $dMNL[];\n"; $subExpr += "clear( $dMNL );\n"; $subExpr += "float $dMXL[];\n"; $subExpr += "clear( $dMXL );\n"; $subExpr += "\n"; for( $i = 0; $i < size( $mainManips ); $i ++ ) { $subExpr += ("$L["+$i+"] = "+$mainManips[$i]+$locationString+";\n"); $subExpr += ("$MND["+$i+"] = "+$mainManips[$i]+$minDistString+";\n"); $subExpr += ("$MXD["+$i+"] = "+$mainManips[$i]+$maxDistString+";\n"); $subExpr += ("$MNL["+$i+"] = "+$mainManips[$i]+$minLocationString+";\n"); $subExpr += ("$MXL["+$i+"] = "+$mainManips[$i]+$maxLocationString+";\n"); } $subExpr += "\n"; $subExpr += "if( "+$flowGroup+".smoothSubManips == 1 )\n"; $subExpr += "{\n"; $subExpr += "int $i;\n"; $subExpr += "for( $i = 0; $i < size( $L ); $i ++ )\n"; $subExpr += "{\n"; $subExpr += "\tif( $i == 0 )\n"; $subExpr += "\t{\n"; $subExpr += "\t\t$dL[$i] = $L[1] - $L[0];\n"; $subExpr += "\t\t$dMND[$i] = $MND[1] - $MND[0];\n"; $subExpr += "\t\t$dMXD[$i] = $MXD[1] - $MXD[0];\n"; $subExpr += "\t\t$dMNL[$i] = $MNL[1] - $MNL[0];\n"; $subExpr += "\t\t$dMXL[$i] = $MXL[1] - $MXL[0];\n"; $subExpr += "\t}\n"; $subExpr += "\telse if( $i == size( $L ) - 1 )\n"; $subExpr += "\t{\n"; $subExpr += "\t\t$dL[$i] = $L[$i] - $L[$i-1];\n"; $subExpr += "\t\t$dMND[$i] = $MND[$i] - $MND[$i-1];\n"; $subExpr += "\t\t$dMXD[$i] = $MXD[$i] - $MXD[$i-1];\n"; $subExpr += "\t\t$dMNL[$i] = $MNL[$i] - $MNL[$i-1];\n"; $subExpr += "\t\t$dMXL[$i] = $MXL[$i] - $MXL[$i-1];\n"; $subExpr += "\t}\n"; $subExpr += "\telse\n"; $subExpr += "\t{\n"; $subExpr += "\t\tfloat $diff1 = max(.01,$L[$i] - $L[$i-1]);\n"; $subExpr += "\t\tfloat $diff2 = max(.01,$L[$i+1] - $L[$i]);\n"; $subExpr += "\t\tfloat $factor = min(2.0, max($diff1/$diff2,$diff2/$diff1));\n"; $subExpr += "\t\t$dL[$i] = min( $L[$i] - $L[$i-1], $L[$i+1] - $L[$i] ) * $factor;\n"; $subExpr += "\t\t$diff1 = $MND[$i] - $MND[$i-1];\n"; $subExpr += "\t\t$diff2 = $MND[$i+1] - $MND[$i];\n"; $subExpr += "\t\t$dMND[$i] = min( $MND[$i] - $MND[$i-1], $MND[$i+1] - $MND[$i] ) * $factor;\n"; $subExpr += "\t\t$diff1 = $MXD[$i] - $MXD[$i-1];\n"; $subExpr += "\t\t$diff2 = $MXD[$i+1] - $MXD[$i];\n"; $subExpr += "\t\t$dMXD[$i] = min( $MXD[$i] - $MXD[$i-1], $MXD[$i+1] - $MXD[$i] ) * $factor;\n"; $subExpr += "\t\t$diff1 = $MNL[$i] - $MNL[$i-1];\n"; $subExpr += "\t\t$diff2 = $MNL[$i+1] - $MNL[$i];\n"; $subExpr += "\t\t$dMNL[$i] = min( $MNL[$i] - $MNL[$i-1], $MNL[$i+1] - $MNL[$i] ) * $factor;\n"; $subExpr += "\t\t$diff1 = $MXL[$i] - $MXL[$i-1];\n"; $subExpr += "\t\t$diff2 = $MXL[$i+1] - $MXL[$i];\n"; $subExpr += "\t\t$dMXL[$i] = min( $MXL[$i] - $MXL[$i-1], $MXL[$i+1] - $MXL[$i] ) * $factor;\n"; $subExpr += "\t}\n"; $subExpr += "}\n"; $subExpr += $subExprHermite; $subExpr += "}\n"; $subExpr += "else\n"; $subExpr += "{\n"; $subExpr += $subExprLinstep; $subExpr += "}\n"; $subExpr += "\n"; } // aliasAttr "displayFlow" ($flowGroup+".visibility"); addAttr -at bool -dv 0 -ln "displaySubManips" $flowGroup; setAttr -keyable 1 ($flowGroup+".displaySubManips"); for( $i = 0; $i < size($subManips); $i ++ ) { connectAttr ($flowGroup+".displaySubManips") ($subManips[$i]+".visibility"); } // // The "showTrueManipShape" attribute determins how the // manipulators are drawn. If it is FALSE, the default, // then the full, smooth manipulator surfaces that the // effect ramps are sampling are shown. If it is TRUE, // then only the resolution planes are shown. These are // the polygonal surfaces showing the exact shape that the // effect is working with. // addAttr -at bool -dv 0 -ln "showTrueManipShape" $flowGroup; createNode -name "doNotShowTrueManipShape#" reverse; string $reverseNode = getSelectedObject( 0 ); connectAttr ($flowGroup+".showTrueManipShape") ($reverseNode+".inputX"); setAttr -keyable 1 ($flowGroup+".showTrueManipShape"); for( $i = 0; $i < size($mainResPlanes); $i ++ ) { connectAttr ($flowGroup+".showTrueManipShape") ($mainResPlanes[$i]+".visibility"); } for( $i = 0; $i < size($subResPlanes); $i ++ ) { connectAttr ($flowGroup+".showTrueManipShape") ($subResPlanes[$i]+".visibility"); } for( $i = 0; $i < size($lofts); $i ++ ) { connectAttr ($reverseNode+".outputX") ($lofts[$i]+".visibility"); } addAttr -at bool -dv 0 -ln "smoothSubManips" $flowGroup; setAttr -keyable -1 ($flowGroup+".smoothSubManips"); if( $subControlResolution > 0 ) { expression -alwaysEvaluate false -string $subExpr -name "SubControlInterpolationExpr#"; } select $minCurves; loft -ch 1 -u 1 -c 0 -ar 0 -d 1 -rn 0 -po 0; rename "MinLoft"; string $minLoft = getSelectedObject( 0 ); addAttr -at bool -dv 0 -ln "displayMinLoft" $flowGroup; setAttr -keyable 1 ($flowGroup+".displayMinLoft"); connectAttr ($flowGroup+".displayMinLoft") ($minLoft+".visibility"); string $loftShape = getShapeFromObject( $minLoft, 0, 0 ); setAttr ($loftShape+".curvePrecision") 3; setAttr ($loftShape+".curvePrecisionShaded") 1; setAttr ($loftShape+".simplifyMode") 0; setAttr ($loftShape+".simplifyU") 1; setAttr ($loftShape+".simplifyV") 1; setAttr ($loftShape+".divisionsU") 0; setAttr ($loftShape+".divisionsV") 0; setAttr -lock 1 ($loftShape+".curvePrecision"); setAttr -lock 1 ($loftShape+".curvePrecisionShaded"); setAttr -lock 1 ($loftShape+".simplifyMode"); setAttr -lock 1 ($loftShape+".simplifyU"); setAttr -lock 1 ($loftShape+".simplifyV"); setAttr -lock 1 ($loftShape+".divisionsU"); setAttr -lock 1 ($loftShape+".divisionsV"); select $maxCurves; loft -ch 1 -u 1 -c 0 -ar 0 -d 1 -rn 0 -po 0; rename "MaxLoft"; string $maxLoft = getSelectedObject( 0 ); addAttr -at bool -dv 0 -ln "displayMaxLoft" $flowGroup; setAttr -keyable 1 ($flowGroup+".displayMaxLoft"); connectAttr ($flowGroup+".displayMaxLoft") ($maxLoft+".visibility"); $loftShape = getShapeFromObject( $maxLoft, 0, 0 ); setAttr ($loftShape+".curvePrecision") 3; setAttr ($loftShape+".curvePrecisionShaded") 1; setAttr ($loftShape+".simplifyMode") 0; setAttr ($loftShape+".simplifyU") 1; setAttr ($loftShape+".simplifyV") 1; setAttr ($loftShape+".divisionsU") 0; setAttr ($loftShape+".divisionsV") 0; setAttr -lock 1 ($loftShape+".curvePrecision"); setAttr -lock 1 ($loftShape+".curvePrecisionShaded"); setAttr -lock 1 ($loftShape+".simplifyMode"); setAttr -lock 1 ($loftShape+".simplifyU"); setAttr -lock 1 ($loftShape+".simplifyV"); setAttr -lock 1 ($loftShape+".divisionsU"); setAttr -lock 1 ($loftShape+".divisionsV"); select $edgeCurves; loft -ch 1 -u 1 -c 0 -ar 0 -d 1 -rn 0 -po 0; rename "EdgeLoft"; string $edgeLoft = getSelectedObject( 0 ); addAttr -at bool -dv 0 -ln "displayEdgeLoft" $flowGroup; setAttr -keyable 1 ($flowGroup+".displayEdgeLoft"); connectAttr ($flowGroup+".displayEdgeLoft") ($edgeLoft+".visibility"); $loftShape = getShapeFromObject( $edgeLoft, 0, 0 ); setAttr ($loftShape+".curvePrecision") 3; setAttr ($loftShape+".curvePrecisionShaded") 1; setAttr ($loftShape+".simplifyMode") 0; setAttr ($loftShape+".simplifyU") 1; setAttr ($loftShape+".simplifyV") 1; setAttr ($loftShape+".divisionsU") 0; setAttr ($loftShape+".divisionsV") 0; setAttr -lock 1 ($loftShape+".curvePrecision"); setAttr -lock 1 ($loftShape+".curvePrecisionShaded"); setAttr -lock 1 ($loftShape+".simplifyMode"); setAttr -lock 1 ($loftShape+".simplifyU"); setAttr -lock 1 ($loftShape+".simplifyV"); setAttr -lock 1 ($loftShape+".divisionsU"); setAttr -lock 1 ($loftShape+".divisionsV"); addAttr -ln "emitterRate" -dv $emitterRate $flowGroup; setAttr -keyable 1 ($flowGroup+".emitterRate"); // Add randomSpeed and randomRadius before calling // makeParticleFlow, if they are not added into the flow group node. // addAttr -ln randomSpeed -dv 0.0 $flowGroup; setAttr -keyable 1 ($flowGroup+".randomSpeed"); addAttr -ln randomRadius -dv 0.0 $flowGroup; setAttr -keyable 1 ($flowGroup+".randomRadius"); int $manipAttrCount = 5; int $j; for( $i = 0; $i < $manipAttrCount; $i ++ ) { int $useRange = 1; if( ( $i == 3 ) || ( $i == 4 ) ) { $useRange = 0; } for( $j = 0; $j < $controlResolution; $j ++ ) { int $index = $j * $manipAttrCount + $i; if( $useRange == 1 ) { addAttr -ln $newAttrs[$index] -min $minValues[$index] -max $maxValues[$index] -dv $defaultValues[$index] $flowGroup; } else { addAttr -ln $newAttrs[$index] -dv $defaultValues[$index] $flowGroup; } setAttr -keyable 1 ($flowGroup+"."+$newAttrs[$index]); connectAttr ($flowGroup+"."+$newAttrs[$index]) ($destManips[$index]+"."+$destAttrs[$index]); } } addAttr -ln "rampCount" -at long -dv (size($ramps)) $flowGroup; setAttr -lock 1 ($flowGroup+".rampCount"); setAttr -keyable 0 ($flowGroup+".rampCount"); string $rampCenter[] = getMarkedObjects( $ramps[0], "rampCenter" ); connectAttr ($rampCenter[0]+".output3D") ($flowGroup+".selectHandle"); setAttr ($flowGroup+".displayHandle") 1; getAttr ($flowGroup+".selectHandle"); addAttr -at message -multi -indexMatters false -ln "effectStrengthAttribute" $flowGroup; addAttr -at message -multi -indexMatters false -ln "effectStrengthRamp" $flowGroup; addAttr -at message -multi -indexMatters false -ln "effectStrengthArrayMapper" $flowGroup; addAttr -at message -multi -indexMatters false -ln "manipPositionAttribute" $flowGroup; addAttr -at message -multi -indexMatters false -ln "manipPositionArrayMapper" $flowGroup; addAttr -at message -multi -indexMatters false -ln "goalWeightAttribute" $flowGroup; addAttr -at message -multi -indexMatters false -ln "adjustedAgeNormalizedAttribute" $flowGroup; addAttr -dt "string" -ln "surfaceFlowTag" $flowGroup; string $tagValue = getUniqueSurfaceFlowTag(); setAttr -type "string" ($flowGroup+".surfaceFlowTag") $tagValue; select $minLoft $maxLoft $edgeLoft; group; rename "LoftGroup"; string $loftGroup = getSelectedObject( 0 ); shadingNode -asShader lambert -name "surfaceFlowLoftS"; string $shader = getSelectedObject( 0 ); setAttr ($shader+".color") -type double3 1 1 0; setAttr ($shader+".transparency") -type double3 .5 .5 .5; string $shadingGroup = `sets -renderable true -noSurfaceShader true -empty -name "surfaceFlowLoftSG"`; connectAttr ($shader+".outColor") ($shadingGroup+".surfaceShader"); sets -e -forceElement $shadingGroup $loftGroup; // // Set the display properties for the manipulators' polygonal // representation of the resolution. The main manips will be // drawn with thick borders, while the subControl manips are // drawn with a thin border. This allows them to be distiguished // when all of the manips are displayed. // select $mainResPlanes; polyOptions -cm "diffuse" -cs 0 -dv 0 -dc 0 -dt 0 -dmb 0 -db 1 -sb 3.0 -dw 0 -din 0 0 0 0 -duv 0 -uvt 0 -ae -dg 1 -ao; select $subResPlanes; polyOptions -cm "diffuse" -cs 0 -dv 0 -dc 0 -dt 0 -dmb 0 -db 1 -sb 1.0 -dw 0 -din 0 0 0 0 -duv 0 -uvt 0 -ae -dg 1 -ao; // // Set display smoothness for the NURBS part of the manipulators. // select $mainManips; displaySmoothness -du 3 -dv 3 -pointsWire 16 -pointsShaded 4; group; rename "ControlManipsGroup"; string $mainManipGroup = getSelectedObject( 0 ); select $subManips; displaySmoothness -du 0 -dv 0 -pointsWire 4 -pointsShaded 1; if( $subControlResolution > 0 ) group; else group -empty; rename "SubManipsGroup"; string $subManipGroup = getSelectedObject( 0 ); select $mainManipGroup $subManipGroup; group; rename "ManipsGroup"; string $manipGroup = getSelectedObject( 0 ); parent $newSurface $flowGroup; parent $manipGroup $flowGroup; parent $loftGroup $flowGroup; addMarkingAttribute($flowGroup,"flowingParticles",1); addMarkingAttribute($flowGroup,"surfaceFlowEmitter",0); addMarkingAttribute($flowGroup,"surfaceFlowGoal",0); string $emitter = surfaceFlowEmitter( $flowGroup ); connectAttr ($flowGroup+".emitterRate") ($emitter+".rate"); string $goal = surfaceFlowGoal( $flowGroup ); return $flowGroup; } proc string[] makeParticleFlow( string $flow, string $particle, string $minRatioAttr, string $maxRatioAttr, string $newGoalAttribute, float $lifespan ) { // Get surface flow's control ramps. // string $ramps[] = surfaceFlowRamps( $flow ); if( size($ramps) == 0 ) { error("The surface flow, \""+$flow+"\", has no controls."); } // Get surface flow emitter. // string $emitter = surfaceFlowEmitter( $flow ); if( $emitter == "" ) { error("The surface flow, \""+$flow+"\", has no surface emitter."); } // Get surface flow goal object(locator). // string $goalLocator = surfaceFlowGoal( $flow ); if( $goalLocator == "" ) { error("The surface flow, \""+$flow+"\", has no goal object."); } // Get particleShape from input particle. If not exist, create one. // string $particleShape = ""; string $givenPShape[] = `ls -o -dag -s -type particle $particle`; if( size($givenPShape) > 0 ) { $particleShape = $givenPShape[0]; } else { string $particleObj[] = `particle`; $particleShape = $particleObj[1]; } // If bad particleShape, return from hear. // if( $particleShape == "" ) { error("There is not valid particle object for "+$flow+"."); } //setAttr ($particleShape+".particleRenderType") 7; // // Start making particle flow. // // Connect the emitter with the particle. // connectDynamic -em $emitter $particleShape; // Add attributes into the given particleShape. // Those new attributes are necessary to control the flow effects. // if( !`attributeQuery -node $particleShape -exists parentU` ) addAttr -ln parentU -dt doubleArray $particleShape; if( !`attributeQuery -node $particleShape -exists parentU0` ) addAttr -ln parentU0 -dt doubleArray $particleShape; if( !`attributeQuery -node $particleShape -exists parentV` ) addAttr -ln parentV -dt doubleArray $particleShape; if( !`attributeQuery -node $particleShape -exists parentV0` ) addAttr -ln parentV0 -dt doubleArray $particleShape; setAttr ($particleShape+".lifespanMode") 1; setAttr ($particleShape+".lifespan") $lifespan; if( !`attributeQuery -node $particleShape -exists ageNormalized` ) addAttr -ln ageNormalized -dt doubleArray $particleShape; // "adjustedAgeNormalized#" is used for multi-flow controls. // string $adjustedAge = getUniqueAttrName( $particleShape, "adjustedAgeNormalized#" ); addAttr -ln $adjustedAge -dt doubleArray $particleShape; // Connect adjustedAge stuff(adjustedAgeNormalized attribute only) with he flow. // connectAttr -na ($particleShape+"."+$adjustedAge) ($flow+".adjustedAgeNormalizedAttribute"); // Add "randomPosition" for random motion control. // if( !`attributeQuery -node $particleShape -exists randomPosition` ) addAttr -ln "randomPosition" -dt vectorArray $particleShape; if( !`attributeQuery -node $particleShape -exists randomPosition0` ) addAttr -ln "randomPosition0" -dt vectorArray $particleShape; if( !`attributeQuery -node $particleShape -exists goalOffset` ) addAttr -ln goalOffset -dt vectorArray $particleShape; if( !`attributeQuery -node $particleShape -exists goalOffset0` ) addAttr -ln goalOffset0 -dt vectorArray $particleShape; // Connect the particle with the goal. // string $oldGoalWeightAttrs[] = `listAttr -multi -string "goalWeight" $particleShape`; goal -w 1 -utr 0 -g $goalLocator $particleShape; string $newGoalWeightAttrs[] = `listAttr -multi -string "goalWeight" $particleShape`; string $goalAttr = ""; int $g; for( $g = 0; $g < size($newGoalWeightAttrs); $g ++ ) { if( findInStringArray( $newGoalWeightAttrs[$g], $oldGoalWeightAttrs ) == -1 ) $goalAttr = $newGoalWeightAttrs[$g]; } if( $goalAttr != "" ) { setAttr -lock 1 ($particleShape+"."+$goalAttr); } // Connect goal stuff(goalWeight attribute only) with the flow. // This connection is for finding the attribute from the flow group node // and then the attribute can be easily deleted when disable the flow. // connectAttr -na ($particleShape+"."+$goalAttr) ($flow+".goalWeightAttribute"); // Connect particle with each ramp? // int $numRamps = size($ramps); string $manipNames[]; clear( $manipNames ); string $manipArrayMappers[]; int $i; for( $i = 0; $i < $numRamps; $i ++ ) { $manipNames[$i] = getUniqueAttrName( $particleShape, "manip_#_Position" ); addAttr -ln $manipNames[$i] -dt vectorArray $particleShape; $manipArrayMappers = `arrayMapper -target $particleShape -inputU parentU -inputV parentV -destAttr $manipNames[$i] -mapTo $ramps[$i]`; // Conect manip stuff with the flow for easily handling from the flow. // connectAttr -na ($particleShape+"."+$manipNames[$i]) ($flow+".manipPositionAttribute"); connectAttr -na ($manipArrayMappers[0]+".message") ($flow+".manipPositionArrayMapper"); // // Disconnect the ramp's outColor attribute from the arrayMapper. // This connection is only used for arrayMappers that are a part of // some rendering network. These arrayMappers and ramps are a part // of the dynamics computation. // disconnectAttr ($ramps[$i]+".outColor") ($manipArrayMappers[0]+".computeNodeColor"); } // Create another ramp to drive effectStrength, if the effectStrength // has not exist and not been controlled. // string $EStrengthAttr = getUniqueAttrName($particleShape,"effectStrength#"); addAttr -ln $EStrengthAttr -dt doubleArray $particleShape; string $ESRamp = `shadingNode -asTexture ramp`; $ESRamp = `rename $ESRamp "SurfaceFlowStrength#"`; removeMultiInstance -break true ($ESRamp+".colorEntryList[1]"); removeMultiInstance -break true ($ESRamp+".colorEntryList[2]"); setAttr ($ESRamp+".colorEntryList[0].color") -type double3 1 1 1; string $strengthArrayMapper[] = `arrayMapper -target $particleShape -inputV $adjustedAge -destAttr $EStrengthAttr -mapTo $ESRamp`; // Conect particle effectStrength stuff(attribute, ramp, arrayMapper) with the flow. // connectAttr -na ($particleShape+"."+$EStrengthAttr) ($flow+".effectStrengthAttribute"); connectAttr -na ($ESRamp+".message") ($flow+".effectStrengthRamp"); connectAttr -na ($strengthArrayMapper[0]+".message") ($flow+".effectStrengthArrayMapper"); // // Disconnect the ramp's outColor attribute from the arrayMapper. // This connection is only used for arrayMappers that are a part of // some rendering network. These arrayMappers and ramps are a part // of the dynamics computation. // disconnectAttr ($ESRamp+".outColor") ($strengthArrayMapper[0]+".computeNodeColor"); // creatation expression to initialize. // string $drivingFlows[] = surfaceFlowsDrivingParticle( $particleShape ); int $flowCount = size( $drivingFlows ); string $cExpression = `dynExpression -q -c -s $particleShape`; if( $flowCount == 0 ) { $cExpression += ("// _SF_INIT_TAG\n"); $cExpression += ("// NOTE 1: Don't remove the tag, _SF_INIT_TAG.\n"); $cExpression += ("// NOTE 2: If adding lines in between _SF_INIT_TAG, they may be deleted when this particle is not driven by any surface flow object.\n"); $cExpression += ("//\n"); $cExpression += ("float $SFMin, $SFMax;\n\n"); $cExpression += ("goalPP = 0;\n"); $cExpression += ("goalOffset = "+$manipNames[0]+";\n"); // Initialize the randomPosition attribute here. // $cExpression += ("// Initialize randomPosition attribute.\n"); $cExpression += ("//\n"); $cExpression += ("vector $idVector = particleId;\n"); $cExpression += ("randomPosition = dnoise( $idVector * 10.0 ) * 100.0;\n"); $cExpression += ("// _SF_INIT_TAG\n"); } string $flowTag = surfaceFlowTag( $flow ); $cExpression += ("\n\n"); $cExpression += ("// "+$flowTag+"\n"); $cExpression += ("// NOTE 1: Don't remove the tag, "+$flowTag+".\n"); $cExpression += ("// NOTE 2: If adding lines in between "+$flowTag+", they may be deleted when this particle is not driven by the surface flow object, "+$flow+".\n"); $cExpression += ("//\n"); $cExpression += ("$SFMin = min("+$flow+"."+$maxRatioAttr+", "+$flow+"."+$minRatioAttr+");\n"); $cExpression += ("$SFMax = max("+$flow+"."+$maxRatioAttr+", "+$flow+"."+$minRatioAttr+");\n"); $cExpression += ("if( $SFMin == $SFMax )\n"); $cExpression += ("{\n"); $cExpression += (" $SFMin = max($SFMin - 0.01, 0.0);\n"); $cExpression += (" $SFMax = min($SFMax + 0.01, 1.0);\n"); $cExpression += ("}\n"); $cExpression += ($adjustedAge +" = (ageNormalized - $SFMin)/($SFMax-$SFMin);\n"); $cExpression += ("// "+$flowTag+"\n"); dynExpression -c -s $cExpression $particleShape; // runtime expression to compute goalOffset. // string $rExpression = `dynExpression -q -r -s $particleShape`; if( $flowCount == 0 ) { $rExpression += ("// _SF_INIT_TAG\n"); $rExpression += ("// NOTE 1: Don't remove the tag, _SF_INIT_TAG.\n"); $rExpression += ("// NOTE 2: If adding lines in between _SF_INIT_TAG, they may be deleted when this particle is not driven by any surface flow object.\n"); $rExpression += ("//\n"); $rExpression += ("int $i, $SFMinIndex, $SFMaxIndex, $SFNumRamps;\n"); $rExpression += ("float $SFIndex, $SFMin, $SFMax;\n"); $rExpression += ("vector $SFManipPos[];\n\n"); $rExpression += ("goalPP = 0;\n"); $rExpression += ("// _SF_INIT_TAG\n"); } $rExpression += ("\n\n"); $rExpression += ("// "+$flowTag+"\n"); $rExpression += ("// NOTE 1: Don't remove the tag, "+$flowTag+".\n"); $rExpression += ("// NOTE 2: If adding lines in between "+$flowTag+", they may be deleted when this particle is not driven by the surface flow object, "+$flow+".\n"); $rExpression += ("//\n"); $rExpression += ("$SFMin = min("+$flow+"."+$maxRatioAttr+", "+$flow+"."+$minRatioAttr+");\n"); $rExpression += ("$SFMax = max("+$flow+"."+$maxRatioAttr+", "+$flow+"."+$minRatioAttr+");\n"); $rExpression += ("if( $SFMin == $SFMax )\n"); $rExpression += ("{\n"); $rExpression += (" $SFMin = max($SFMin - 0.01, 0.0);\n"); $rExpression += (" $SFMax = min($SFMax + 0.01, 1.0);\n"); $rExpression += ("}\n"); $rExpression += ("if( (ageNormalized <= $SFMax) && (ageNormalized >= $SFMin) )\n"); $rExpression += ("{\n"); $rExpression += (" goalPP = "+$EStrengthAttr+" * "+$newGoalAttribute+";\n"); $rExpression += (" "+$adjustedAge+" = (ageNormalized - $SFMin)/($SFMax-$SFMin);\n\n"); $rExpression += (" clear( $SFManipPos );\n"); int $i; for( $i = 0; $i < $numRamps; $i ++ ) { $rExpression += (" $SFManipPos["+$i+"] = "+$manipNames[$i]+";\n"); } $rExpression += ("\n"); $rExpression += (" $SFNumRamps = "+$flow+".rampCount;\n"); $rExpression += (" $SFIndex = "+$adjustedAge+" * ($SFNumRamps - 1);\n"); $rExpression += (" $SFMinIndex = $SFIndex;\n\n"); // Compute random motion offset and add it into goalOffset. // $rExpression += (" // Compute random motion offset.\n"); $rExpression += (" //\n"); $rExpression += (" float $randomSpeed = "+$flow+".randomSpeed;\n"); $rExpression += (" float $randomRadius = "+$flow+".randomRadius;\n"); $rExpression += (" vector $randomPos = "+$particleShape+".randomPosition;\n"); $rExpression += (" vector $randomOffset = dnoise( $randomPos + (time * $randomSpeed) ) * $randomRadius;\n\n"); $rExpression += (" if( $SFIndex == $SFMinIndex )\n"); $rExpression += (" {\n"); $rExpression += (" vector $gOffset = $SFManipPos[$SFMinIndex] + $randomOffset;\n"); $rExpression += (" "+$particleShape+".goalOffset = $gOffset;\n"); $rExpression += (" }\n"); $rExpression += (" else\n"); $rExpression += (" {\n"); $rExpression += (" $SFMaxIndex = $SFMinIndex + 1;\n"); $rExpression += (" float $remainder = $SFIndex - $SFMinIndex;\n"); $rExpression += (" vector $gOffset = ($SFManipPos[$SFMinIndex] + ($remainder * ($SFManipPos[$SFMaxIndex] - $SFManipPos[$SFMinIndex])));\n"); $rExpression += (" $gOffset += $randomOffset;\n"); $rExpression += (" "+$particleShape+".goalOffset = $gOffset;\n"); $rExpression += (" }\n"); $rExpression += ("}\n"); $rExpression += ("// "+$flowTag+"\n"); dynExpression -r -s $rExpression $particleShape; string $result[]; clear( $result ); $result[0] = $particleShape; $result[1] = $goalAttr; $result[2] = $ESRamp; return( $result ); } proc string doFlowAlongSurface( string $name, string $flowObject, string $existingParticleObject, int $createParticleObject, float $lifespan, string $type, int $controlResolution, int $subControlResolution, int $manipResolution, float $goalWeight, float $emitterRate, float $minAgeRatio, float $maxAgeRatio ) { if( $flowObject == "" ) { error("Must supply either a NURBS surface or a surface flow group when using the flowAlongSurface effect."); } if( isObjectIntermediate( $flowObject ) == 1 ) { warning("The object, \""+$flowObject+"\", is intermediate. Skipping"); return ""; } string $oldNodes[] = `ls`; string $surface = ""; string $flowGroup = ""; if( isSurfaceFlow( $flowObject ) == 1 ) { $flowGroup = $flowObject; } else { string $surfaces[] = `ls -objectsOnly -dag -type nurbsSurface $flowObject`; if( size( $surfaces ) > 0 ) { $surface = $surfaces[0]; } } if( ( $flowGroup == "" ) && ( $surface == "" ) ) { error("Must supply either a NURBS surface or a surface flow group when using the flowAlongSurface effect."); } else if( ($flowGroup == "" ) && ( $surface != "" ) ) { $flowGroup = makeSurfaceFlowGroup( $surface, $name, $type, $controlResolution, $subControlResolution, $manipResolution, $goalWeight, $emitterRate, $minAgeRatio, $maxAgeRatio ); addMarkingAttribute( $flowGroup, "nodesToDelete", 1 ); } if( $existingParticleObject != "" ) { string $shapes[] = getShapesFromObject( $existingParticleObject, 0 ); if( size( $shapes ) == 0 ) $existingParticleObject = ""; else if( size( $shapes ) > 1 ) { warning("More than one particle shape found under \""+$existingParticleObject+"\". Creating a new one."); $existingParticleObject = ""; } } if( $existingParticleObject != "" ) { // If $existingParticleObject exists, // check if $existingParticleObject belongs to $flowGroup. // If true, return now. // if( isParticleInSurfaceFlow($flowGroup, $existingParticleObject) ) { warning("The input particle object, \""+$existingParticleObject+"\", is already controlled by the given surface flow, \""+$flowGroup+"\". No work done."); return $flowGroup; } } if( ( $existingParticleObject != "" ) || ( $createParticleObject == 1 ) ) { // string $minRatioAttr = getUniqueAttrName( $flowGroup, "min_#_Ratio" ); string $minRatioAttr = getUniqueAttrName( $flowGroup, "minAgeRatio_#" ); addAttr -ln $minRatioAttr -dv $minAgeRatio $flowGroup; setAttr -keyable 1 ($flowGroup+"."+$minRatioAttr); // string $maxRatioAttr = getUniqueAttrName( $flowGroup, "max_#_Ratio" ); string $maxRatioAttr = getUniqueAttrName( $flowGroup, "maxAgeRatio_#" ); addAttr -ln $maxRatioAttr -dv $maxAgeRatio $flowGroup; setAttr -keyable 1 ($flowGroup+"."+$maxRatioAttr); string $newGoalAttribute = ""; string $newGoalWeightAttr = getUniqueAttrName( $flowGroup, "goalWeight_#" ); addAttr -ln $newGoalWeightAttr -dv $goalWeight $flowGroup; $newGoalAttribute = ($flowGroup+"."+$newGoalWeightAttr); setAttr -keyable 1 $newGoalAttribute; string $flowStuff[] = makeParticleFlow( $flowGroup, $existingParticleObject, $minRatioAttr, $maxRatioAttr, $newGoalAttribute, $lifespan ); string $flowParticles = $flowStuff[0]; markObjectWithAttribute($flowParticles,$flowGroup,"flowingParticles"); if( 0 ) // $flowStuff[1] != "" ) { // string $newGoalWeightAttr = getUniqueAttrName( $flowGroup, "goal_#_Weight" ); string $newGoalWeightAttr = getUniqueAttrName( $flowGroup, "goalWeight_#" ); addAttr -ln $newGoalWeightAttr -dv $goalWeight $flowGroup; setAttr -keyable 1 ($flowGroup+"."+$newGoalWeightAttr); string $goalWeightAttr = ($flowParticles+"."+$flowStuff[1]); connectAttr -f ($flowGroup+"."+$newGoalWeightAttr) $goalWeightAttr; } else { // // If this value is "", then the particle object is already // following the gicen goal object, and no work is needed // here. // } string $seeds[] = `listAttr -multi -string "seed" $flowParticles`; string $flowingParticles[] = surfaceFlowParticles( $flowGroup ); if( size($flowingParticles) > 0 ) setAttr ($flowParticles+"."+$seeds[size($seeds)-1]) (size($flowingParticles)); } string $newNodes[] = `ls`; print("// Performing post-processes for the surface flow. This may take several minutes.\n"); markNewNonDagNodes( $flowGroup, $oldNodes, $newNodes ); markNodesNonHistoricallyInteresting( $flowGroup ); print("// ...Done with post-processes.\n"); select $flowGroup; return $flowGroup; } /////////////////////////////////////////////////////////////////////////////////////// global proc string[] main_flowAlongSurfaces( string $name, int $createParticle, float $lifespan, int $createParticleForEachFlow, string $type, int $controlResolution, int $subControlResolution, int $manipResolution, float $goalWeight, float $emitterRate, float $minAgeRatio, float $maxAgeRatio ) { string $results[]; clear( $results ); if( `licenseCheck -type complete` == 0 ) { // warning("You are not licensed to use the Flow Along Along Surface Effect."); error("You are not licensed to use the Flow Along Along Surface Effect."); return $results; } string $flowObjects[] = selectedSurfaceFlowsAndSurfaces(); string $particles[] = `ls -sl -objectsOnly -dag -type particle`; if( size( $flowObjects ) == 0 ) { // warning("No NURBS surfaces or surface flow objects selected. Can not continue with flowAlongSurfaces."); error("No NURBS surfaces or surface flow objects selected. Can not continue with flowAlongSurfaces."); return $results; } if( size( $particles ) == 0 ) { int $f; if( $createParticle == 1 ) { float $newMin = 0; float $newMax = 0; float $range = ($maxAgeRatio-$minAgeRatio); float $stepSize = $range / size($flowObjects); if( $createParticleForEachFlow == 1 ) { $newMin = $minAgeRatio; $newMax = $maxAgeRatio; } else { $newMin = $minAgeRatio; $newMax = $minAgeRatio + $stepSize; } string $flow = flowAlongSurface( $name, $flowObjects[0], "", 1, $lifespan, $type, $controlResolution, $subControlResolution, $manipResolution, $goalWeight, $emitterRate, $newMin, $newMax ); string $particles[] = surfaceFlowParticles( $flow ); string $particleObject = $particles[0]; if( $flow != "" ) $results = appendSingleToStringArray( $results, $flow ); for( $f = 1; $f < size( $flowObjects ); $f ++ ) { int $newParticle = 1; if( $createParticleForEachFlow == 0 ) { $newParticle = 0; $newMin = $minAgeRatio + $stepSize * $f; $newMax = $minAgeRatio + $stepSize * ($f + 1.0); } else { $newMin = $minAgeRatio; $newMax = $maxAgeRatio; } if( $newParticle == 0 ) { $flow = flowAlongSurface( $name, $flowObjects[$f], $particleObject, 0, $lifespan,$type, $controlResolution, $subControlResolution, $manipResolution, $goalWeight, 0, $newMin, $newMax ); if( $flow != "" ) $results = appendSingleToStringArray( $results, $flow ); } else { $flow = flowAlongSurface( $name, $flowObjects[$f], "", 1, $lifespan, $type, $controlResolution, $subControlResolution, $manipResolution, $goalWeight, $emitterRate, $newMin, $newMax ); if( $flow != "" ) $results = appendSingleToStringArray( $results, $flow ); } } } else { string $flow = ""; for( $f = 0; $f < size( $flowObjects ); $f ++ ) { $flow = flowAlongSurface( $name, $flowObjects[$f], "", 0, $lifespan, $type, $controlResolution, $subControlResolution, $manipResolution, $goalWeight, $emitterRate, $minAgeRatio, $maxAgeRatio ); if( $flow != "" ) $results = appendSingleToStringArray( $results, $flow ); } } } else { string $flow = ""; int $f; int $p; for( $p = 0; $p < size( $particles ); $p ++ ) { for( $f = 0; $f < size( $flowObjects ); $f ++ ) { $flow = flowAlongSurface( $name, $flowObjects[$f], $particles[$p], 0, $lifespan, $type, $controlResolution, $subControlResolution, $manipResolution, $goalWeight, $emitterRate, $minAgeRatio, $maxAgeRatio ); if( $flow != "" ) $results = appendSingleToStringArray( $results, $flow ); } } } select $results; return $results; } global proc string main_flowAlongSurface( string $name, string $flowObject, string $existingParticleObject, int $createParticleObject, float $lifespan, string $type, int $controlResolution, int $subControlResolution, int $manipResolution, float $goalWeight, float $emitterRate, float $minAgeRatio, float $maxAgeRatio ) { string $result = ""; if( `licenseCheck -type complete` == 0 ) { // warning("You are not licensed to use the Flow Along Along Surface Effect."); error("You are not licensed to use the Flow Along Along Surface Effect."); return $result; } waitCursor -state on; cycleCheck -e off; if( catch( $result = doFlowAlongSurface( $name, $flowObject, $existingParticleObject, $createParticleObject, $lifespan, $type, $controlResolution, $subControlResolution, $manipResolution, $goalWeight, $emitterRate, $minAgeRatio, $maxAgeRatio ) ) == 1 ) { // warning("Some error occurred during the execution of \"flowAlongSurface\" for \""+$flowObject+"\". Results may be invalid."); waitCursor -state off; error("Some error occurred during the execution of \"flowAlongSurface\" for \""+$flowObject+"\". Results may be invalid."); } waitCursor -state off; return $result; } global proc main_deleteSurfaceFlow( string $flow, int $deleteParticle ) { if( `licenseCheck -type complete` == 0 ) { // warning("You are not licensed to use the Flow Along Along Surface Effect."); error("You are not licensed to use the Flow Along Along Surface Effect."); return; } if( isSurfaceFlow( $flow ) == 0 ) { error("The object, \""+$flow+"\", is not a surface flow object."); } int $i, $count; if( $deleteParticle ) { // Get all particles which are driven by the $flow. // Then delete them if not driving by other surface flow objects. // string $flowingParticles[] = surfaceFlowParticles( $flow ); string $drivingFlow[]; $count = size($flowingParticles); for( $i = 0; $i < $count; $i++ ) { $drivingFlow = surfaceFlowsDrivingParticle($flowingParticles[$i]); if( (size($drivingFlow) == 1) && ($drivingFlow[0] == $flow) ) { string $parent[]=`listRelatives -parent $flowingParticles[$i]`; delete $parent[0]; } else { removeParticleFromSurfaceFlow( $flow, $flowingParticles[$i] ); } } } else { // Have to remove all particle objects from the $flow. // But particles will not be deleted. // removeParticlesFromSurfaceFlow( $flow ); } // Delete non-dag nodes which have been created for the $flow. // string $nonDagNodes[] = surfaceFlowNodesToDelete( $flow ); $count = size( $nonDagNodes ); for( $i = 0; $i < $count; $i++ ) { if( `objExists $nonDagNodes[$i]` == 1 ) { delete $nonDagNodes[$i]; } } // Delete flow. // delete $flow; } global proc main_deleteSurfaceFlows( int $deleteFlow, int $deleteParticle ) // // Descriptions: // UI will execute this procedure based on selected surface flow groups. // // Logic 1: if $deleteFlow && $deleteParticle, all particles driven by // the selected flows will be deleted. Then delete flows. // // Logic 2: if $deleteFlow && !$deleteParticle, break all particles' // connections with selected flows. Then delete flows only. // // Logic 3: if !$deleteFlow, ignore $deleteParticle. This procedure // will call removeParticlesFromSurfaceFlow to break all particle // connections with selected flows. Delete nothing. // // But if there are also some particle selected, remove each // selected particle from each selected surface flow. // { if( `licenseCheck -type complete` == 0 ) { // warning("You are not licensed to use the Flow Along Along Surface Effect."); error("You are not licensed to use the Flow Along Along Surface Effect."); return; } // Get seleted surface flow groups. // string $flows[] = selectedSurfaceFlows(); string $particles[] = `ls -sl -objectsOnly -dag -type particle`; int $i; int $flowCount = size( $flows ); int $particleCount = size( $particles ); if( $flowCount == 0 ) { // warning("There is not any surface flow group selected."); error("There is not any surface flow group selected."); return; } for( $i = 0; $i < $flowCount; $i++ ) { if( $deleteFlow != 0 ) { deleteSurfaceFlow( $flows[$i], $deleteParticle ); } else if( $particleCount == 0 ) { removeParticlesFromSurfaceFlow( $flows[$i] ); } else { int $j; for( $j = 0; $j < $particleCount; $j++ ) { removeParticleFromSurfaceFlow( $flows[$i], $particles[$j] ); } } } } global proc main_removeParticlesFromSurfaceFlow( string $flow ) { if( `licenseCheck -type complete` == 0 ) { // warning("You are not licensed to use the Flow Along Along Surface Effect."); error("You are not licensed to use the Flow Along Along Surface Effect."); return; } if( isSurfaceFlow( $flow ) == 0 ) { error("The object, \""+$flow+"\", is not a surface flow object."); } string $flowParticles[] = surfaceFlowParticles( $flow ); int $numParticles = size( $flowParticles ); if( $numParticles == 0 ) return; int $i; for( $i = 0; $i < $numParticles; $i ++ ) { removeParticleFromSurfaceFlow( $flow, $flowParticles[$i] ); } } global proc main_removeParticleFromSurfaceFlow( string $flow, string $particleShape ) { if( `licenseCheck -type complete` == 0 ) { // warning("You are not licensed to use the Flow Along Along Surface Effect."); error("You are not licensed to use the Flow Along Along Surface Effect."); return; } if( isSurfaceFlow( $flow ) == 0 ) { error("The object, \""+$flow+"\", is not a surface flow object."); } if( `objExists $particleShape` == 0 ) { error("The particleShape, \""+$particleShape+"\", does not exist."); } // Get the shape, in case $particleShape is not a shape. // string $particleShapes[] = `ls -o -dag -s -type particle $particleShape`; if( size($particleShapes) == 0 ) return; $particleShape = $particleShapes[0]; // Disconnect particleShape with the emitter. // string $emitter = surfaceFlowEmitter( $flow ); connectDynamic -d -em $emitter $particleShape; // Remove expression for surface flow. // string $expression, $newExpression; string $tagStr = surfaceFlowTag( $flow ); string $searchStr = "\n*// "+$tagStr+".*"+$tagStr+"\n*"; string $replaceStr = "\n\n"; string $drivingFlows[] = surfaceFlowsDrivingParticle( $particleShape ); int $flowCount = size( $drivingFlows ); string $searchStrInit = "\n*// _SF_INIT_TAG.*_SF_INIT_TAG\n*"; // For creatation expression. // $expression = `dynExpression -q -c -s $particleShape`; $newExpression = substitute( $searchStr, $expression, $replaceStr ); if( $flowCount == 1 ) $newExpression = substitute( $searchStrInit, $newExpression, $replaceStr ); dynExpression -c -s $newExpression $particleShape; // For runtime expression. // $expression = `dynExpression -q -r -s $particleShape`; $newExpression = substitute( $searchStr, $expression, $replaceStr ); if( $flowCount == 1 ) $newExpression = substitute( $searchStrInit, $newExpression, $replaceStr ); dynExpression -r -s $newExpression $particleShape; // Delete randomPosition attribute if $flowCount == 1. The reason is that // the particle object has only one attribute for random motion control. // If $flowCount == 1(the particle has only flow control), we can delete // this attribute. // if( $flowCount == 1 ) { if( `attributeQuery -node $particleShape -exists randomPosition` ) { deleteAttr -at "randomPosition" $particleShape; } if( `attributeQuery -node $particleShape -exists randomPosition0` ) { deleteAttr -at "randomPosition0" $particleShape; } } // // Start breaking connections and deleting attributes and some nodes. // int $i, $count; // Remove effect strength stuff. // string $strengthConnections[] = surfaceFlowEffectAttrConnections( $flow, $particleShape ); string $strengthObjects[] = surfaceFlowEffectStrengthObjects( $flow, $particleShape ); // We need to break connections: // particleShape.effectStrength# <-> flow.effectStrengthAttribute // strengthRamp.message <-> flow.effectStrengthRamp // strengthArrayMapper.message <-> flow.effectStrengthArrayMapper // // Then delete strengthRamp and strengthArrayMapper. // Then delete effectStrength attribute from $particleShape. // $count = size($strengthConnections) - 1; for( $i = 1; $i < $count; $i = $i + 2 ) { disconnectAttr ($strengthConnections[$i]) ($strengthConnections[$i+1]); } deleteAttr -at $strengthConnections[0] $particleShape; delete $strengthObjects; // Remove manipPosition stuff. // string $manipStuff[] = surfaceFlowManipPositionAttributes( $flow, $particleShape ); // We need to break connections between: // particleShape.manip_#_Position <-> flow.manipPositionAttribute // manipPositionArrayMapper.message <-> flow.manipPositionArrayMapper // // Then delete manipPositionArrayMapper, and maniPositionRamp????. // Then delete manip_#_Position attributes from $particleShape. // Then delete arrayMappers. // int $manipAttrCount = $manipStuff[0]; int $startCount = $manipAttrCount + 1; $count = size($manipStuff) - 1; for( $i = $startCount; $i < $count; $i = $i + 2 ) { disconnectAttr ($manipStuff[$i]) ($manipStuff[$i+1]); } for( $i = 1; $i <= $manipAttrCount; $i++ ) { deleteAttr -at $manipStuff[$i] $particleShape; } string $manipArrayMappers[] = surfaceFlowManipArrayMappers( $flow, $particleShape ); delete $manipArrayMappers; // Remove adjustedAge stuff. // string $adjustedAgeStuff[] = surfaceFlowAdjustedAgeNormalizedAttribute( $flow, $particleShape ); // We need to break connection between: // particleShape.adjustedAgeNormalized <-> flow.adjustedAgeNormalizedAttribute // // Then delete adjustedAgeNormalized attribute from the $particleShape. // $count = size($adjustedAgeStuff) - 1; for( $i = 1; $i < $count; $i = $i + 2 ) { disconnectAttr ($adjustedAgeStuff[$i]) ($adjustedAgeStuff[$i+1]); } deleteAttr -at $adjustedAgeStuff[0] $particleShape; // Remove goal stuff. // string $goalStuff[] = surfaceFlowGoalWeightAttribute( $flow, $particleShape ); // We need to break connections between: // particleShape.goalWeight# <-> flow.goalWeightAttribute // and also connections between goalObject and particleShape. // // Then delete goalWeight# attribute from $particleShape. // $count = size($goalStuff) - 1; for( $i = 1; $i < $count; $i = $i + 2 ) { disconnectAttr ($goalStuff[$i]) ($goalStuff[$i+1]); } setAttr -lock 0 ($particleShape+".goalWeight["+$goalStuff[0]+"]"); removeMultiInstance -break true ($particleShape+".goalWeight["+$goalStuff[0]+"]"); removeMultiInstance -break true ($particleShape+".goalActive["+$goalStuff[0]+"]"); removeMultiInstance -break true ($particleShape+".goalGeometry["+$goalStuff[0]+"]"); // Break connections with the flow.flowingParticles. // string $flowingParticles[] = surfaceFlowParticles( $flow ); int $index = findInStringArray( $particleShape, $flowingParticles ); string $connections[] = `listConnections -source true -destination false -connections 1 -plugs 1 -shapes 1 ($flow+".flowingParticles")`; disconnectAttr $connections[$index*2+1] $connections[$index*2]; cleanupSurfaceFlowAttributes( $flow ); } ////////////////////////////////////////////////////////////////////////////////// global proc int main_isSurfaceFlow( string $object ) { if( `objExists $object` == 0 ) { return 0; } if( `attributeQuery -node $object -exists "_surfaceFlowObject"` == 1 ) return 1; else return 0; } global proc string[] main_selectedSurfaceFlows() { string $result[]; clear( $result ); string $selection[] = `ls -objectsOnly -sl`; int $i; for( $i = 0; $i < size( $selection ); $i ++ ) { if( isSurfaceFlow( $selection[$i] ) == 1 ) { if( isObjectIntermediate( $selection[$i] ) == 0 ) { $result = appendSingleToStringArray( $result, $selection[$i] ); } } } return $result; } global proc string[] main_selectedSurfaceFlowsAndSurfaces() { string $result[]; clear( $result ); string $selection[] = `ls -objectsOnly -sl`; int $i; for( $i = 0; $i < size( $selection ); $i ++ ) { if( isSurfaceFlow( $selection[$i] ) == 1 ) { if( isObjectIntermediate( $selection[$i] ) == 0 ) { $result = appendSingleToStringArray( $result, $selection[$i] ); } } else { string $surfaces[] = `ls -objectsOnly -dag -type nurbsSurface $selection[$i]`; int $j; for( $j = 0; $j < size($surfaces); $j ++ ) { if( isObjectIntermediate( $surfaces[$j] ) == 0 ) $result = appendSingleToStringArray( $result, $surfaces[$j] ); } } } return $result; } /////////////////////////////////////////////////////////////////////////////////// global proc int main_isParticleInSurfaceFlow( string $object, string $particle ) { // $object is a flow. if( (`objExists $object` == 0) || (`objExists $particle` == 0) ) { return 0; } // Get particleShape if $particle is not a particleShape. // string $givenShapes[] = `ls -o -dag -s -typ particle $particle`; string $givenShape = $givenShapes[0]; string $flowParticles[] = surfaceFlowParticles( $object ); if( findInStringArray( $givenShape, $flowParticles) != -1 ) return 1; return 0; } global proc string[] main_surfaceFlowParticles( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } $result = getMarkedObjects( $object, "flowingParticles" ); return $result; } global proc string[] main_surfaceFlowsDrivingParticle( string $particle ) { string $result[]; clear( $result ); string $particleShapes[] = `ls -o -dag -s -typ particle $particle`; if( size($particleShapes) == 0 ) return $result; string $particleShape = $particleShapes[0]; string $allNodes[] = `ls`; int $i; for( $i = 0; $i < size( $allNodes ); $i ++ ) { if( isSurfaceFlow( $allNodes[$i] ) == 1 ) { if( isParticleInSurfaceFlow( $allNodes[$i], $particleShape ) ) $result = appendSingleToStringArray( $result, $allNodes[$i] ); } } return $result; } ////////////////////////////////////////////////////////////////////////// global proc string main_surfaceFlowReferenceSurface( string $object ) { if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } // string $surface[] = `listConnections -source true -destination false ($object+".referenceFlowSurface")`; string $surface[] = getMarkedObjects( $object, "referenceFlowSurface" ); if( size($surface) == 0 ) { return ""; } return $surface[0]; } global proc string main_surfaceFlowActualSurface( string $object ) { if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } // string $surface[] = `listConnections -source true -destination false ($object+".actualFlowSurface")`; string $surface[] = getMarkedObjects( $object, "actualFlowSurface" ); if( size($surface) == 0 ) { return ""; } return $surface[0]; } global proc string main_surfaceFlowEmitter( string $object ) { if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } string $result[] = getMarkedObjects( $object, "surfaceFlowEmitter" ); if( size( $result ) == 0 ) { string $lofts[] = surfaceFlowLofts( $object ); if( size($lofts) == 0 ) { return ""; } else { emitter -type surface -mxd 0 -mnd 0 -r 10 -spd 0 -nsp 1 -tsp 0 $lofts[0]; string $emitter = getSelectedObject( 0 ); setAttr ($emitter+".needParentUV") 1; markObjectWithAttribute( $emitter, $object, "surfaceFlowEmitter" ); return $emitter; } } else { return $result[0]; } } global proc string main_surfaceFlowGoal( string $object ) { if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } string $result[] = getMarkedObjects( $object, "surfaceFlowGoal" ); if( size( $result ) == 0 ) { spaceLocator; string $locator = getSelectedObject( 0 ); lockTransformations( $locator ); parent $locator $object; setAttr ($locator+".inheritsTransform") 0; markObjectWithAttribute( $locator, $object, "surfaceFlowGoal" ); hide $locator; setAttr ($locator+".template") 1; return $locator; } else { return $result[0]; } } global proc string[] main_surfaceFlowManips( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } string $mainManips[] = surfaceFlowMainManips( $object ); string $subManips[] = surfaceFlowSubManips( $object ); int $subsPerMain = size($subManips) / (size($mainManips)-1); $result[0] = $mainManips[0]; int $currentSub = 0; int $i; for( $i = 1; $i < size($mainManips); $i ++ ) { int $j; for( $j = $currentSub; $j < ($currentSub + $subsPerMain); $j ++ ) { $result = appendSingleToStringArray( $result, $subManips[$j] ); } $currentSub += $subsPerMain; $result = appendSingleToStringArray( $result, $mainManips[$i] ); } return $result; } global proc string[] main_surfaceFlowRamps( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } string $mainRamps[] = surfaceFlowMainRamps( $object ); string $subRamps[] = surfaceFlowSubRamps( $object ); int $subsPerMain = size($subRamps) / (size($mainRamps)-1); $result[0] = $mainRamps[0]; int $currentSub = 0; int $i; for( $i = 1; $i < size($mainRamps); $i ++ ) { int $j; for( $j = $currentSub; $j < ($currentSub + $subsPerMain); $j ++ ) { $result = appendSingleToStringArray( $result, $subRamps[$j] ); } $currentSub += $subsPerMain; $result = appendSingleToStringArray( $result, $mainRamps[$i] ); } return $result; } global proc string[] main_surfaceFlowLofts( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } string $mainLofts[] = surfaceFlowMainLofts( $object ); string $subLofts[] = surfaceFlowSubLofts( $object ); int $subsPerMain = size($subLofts) / (size($mainLofts)-1); $result[0] = $mainLofts[0]; int $currentSub = 0; int $i; for( $i = 1; $i < size($mainLofts); $i ++ ) { int $j; for( $j = $currentSub; $j < ($currentSub + $subsPerMain); $j ++ ) { $result = appendSingleToStringArray( $result, $subLofts[$j] ); } $currentSub += $subsPerMain; $result = appendSingleToStringArray( $result, $mainLofts[$i] ); } return $result; } global proc string[] main_surfaceFlowResolutionPlanes( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } string $mainResolutionPlanes[] = surfaceFlowMainResolutionPlanes( $object ); string $subResolutionPlanes[] = surfaceFlowSubResolutionPlanes( $object ); int $subsPerMain = size($subResolutionPlanes) / (size($mainResolutionPlanes)-1); $result[0] = $mainResolutionPlanes[0]; int $currentSub = 0; int $i; for( $i = 1; $i < size($mainResolutionPlanes); $i ++ ) { int $j; for( $j = $currentSub; $j < ($currentSub + $subsPerMain); $j ++ ) { $result = appendSingleToStringArray( $result, $subResolutionPlanes[$j] ); } $currentSub += $subsPerMain; $result = appendSingleToStringArray( $result, $mainResolutionPlanes[$i] ); } return $result; } global proc string[] main_surfaceFlowEdgeCurves( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } string $mainEdgeCurves[] = surfaceFlowMainEdgeCurves( $object ); string $subEdgeCurves[] = surfaceFlowSubEdgeCurves( $object ); int $subsPerMain = size($subEdgeCurves) / (size($mainEdgeCurves)-1); $result[0] = $mainEdgeCurves[0]; int $currentSub = 0; int $i; for( $i = 1; $i < size($mainEdgeCurves); $i ++ ) { int $j; for( $j = $currentSub; $j < ($currentSub + $subsPerMain); $j ++ ) { $result = appendSingleToStringArray( $result, $subEdgeCurves[$j] ); } $currentSub += $subsPerMain; $result = appendSingleToStringArray( $result, $mainEdgeCurves[$i] ); } return $result; } global proc string[] main_surfaceFlowMinCurves( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } string $mainMinCurves[] = surfaceFlowMainMinCurves( $object ); string $subMinCurves[] = surfaceFlowSubMinCurves( $object ); int $subsPerMain = size($subMinCurves) / (size($mainMinCurves)-1); $result[0] = $mainMinCurves[0]; int $currentSub = 0; int $i; for( $i = 1; $i < size($mainMinCurves); $i ++ ) { int $j; for( $j = $currentSub; $j < ($currentSub + $subsPerMain); $j ++ ) { $result = appendSingleToStringArray( $result, $subMinCurves[$j] ); } $currentSub += $subsPerMain; $result = appendSingleToStringArray( $result, $mainMinCurves[$i] ); } return $result; } global proc string[] main_surfaceFlowMaxCurves( string $object ) { string $result[]; clear( $result ); if( isSurfaceFlow( $object ) == 0 ) { error("The object, \""+$object+"\", is not a surface flow object."); } string $mainMaxCurves[] = surfaceFlowMainMaxCurves( $object ); string $subMaxCurves[] = surfaceFlowSubMaxCurves( $object ); int $subsPerMain = size($subMaxCurves) / (size($mainMaxCurves)-1); $result[0] = $mainMaxCurves[0]; int $currentSub = 0; int $i; for( $i = 1; $i < size($mainMaxCurves); $i ++ ) { int $j; for( $j = $currentSub; $j < ($currentSub + $subsPerMain); $j ++ ) { $result = appendSingleToStringArray( $result, $subMaxCurves[$j] ); } $currentSub += $subsPerMain; $result = appendSingleToStringArray( $result, $mainMaxCurves[$i] ); } return $result; }